import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TooManyListenersException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;


public class Test {
	String comPort;

	public String[] getPortChoices(){
		String[] portOptions = new String[0];

		CommPortIdentifier portId;

		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		// iterate through the ports.
		Map portOptionsMap = new HashMap();
		while (en.hasMoreElements()) {
			portId = (CommPortIdentifier) en.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				portOptionsMap.put(portId.getName(),"");
			}
			portOptions = new String[portOptionsMap.size()];
			int j = 0;
			for(Iterator i = portOptionsMap.keySet().iterator(); i.hasNext();)
			{
				portOptions[j]=(String)i.next();
				j++;
			}
			Arrays.sort(portOptions, String.CASE_INSENSITIVE_ORDER);
		}
		for(int i=0;i<portOptions.length;i++){
			System.out.println(portOptions[i]);
		}
		return(portOptions);
	}
	
	SerialPort serialPort;
	
	public boolean openPort(String portName){
		try{
			//gnu.io.RXTXPort.staticSetRTS(portName, false);
			CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);
			serialPort = (SerialPort) portId.open("CodeSkin", 2000); // 2000 = block time to wait for open
			serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
			serialPort.setDTR(false);
			return(true);
		} catch (NoSuchPortException e) {
			e.printStackTrace();
		} catch (PortInUseException e) {
			e.printStackTrace();
		} catch (java.lang.UnsatisfiedLinkError e){
			e.printStackTrace();
//		} catch (TooManyListenersException e){
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
		} catch (UnsupportedCommOperationException e) {
			e.printStackTrace();
		}
		return(false);
	}
	
	public boolean closePort(){
		serialPort.close();
		return(true);
	}
	
	Button bO, bC, bK;
	
	public void createTestShell(){
		Display display = new Display();
		final Shell shell = new Shell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);		

		shell.setText("RXTX Tester");
		shell.setLayout(new GridLayout());

		Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData sGd = new GridData();
		sGd.horizontalAlignment = GridData.FILL;
		sGd.grabExcessHorizontalSpace = true;
		separator.setLayoutData(sGd);

		Composite composite = new Composite(shell, SWT.NONE);
		GridLayout layout = new GridLayout();
		composite.setLayout(layout);
		GridData data = new GridData(GridData.FILL);
		data.grabExcessHorizontalSpace = true;
		composite.setLayoutData(data);

		Label lp = new Label(composite, SWT.NONE);
		lp.setText("Port:");
		final Combo portCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
		portCombo.setToolTipText("RS-232 Communication Port.");
		// portCombo.setLayoutData(new RowData(200,20));
		portCombo.setItems(getPortChoices());
		portCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				comPort = portCombo.getText();
			}
		});
		
		bO = new Button(composite,  SWT.PUSH);
		bO.setText("Open");
		GridData bOGd = new GridData();
		bOGd.horizontalAlignment = GridData.FILL;
		bOGd.grabExcessHorizontalSpace = true;
		bO.setLayoutData(bOGd);
		bO.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				if(openPort(portCombo.getText())){
					bO.setEnabled(false);
					bC.setEnabled(true);
					bK.setEnabled(true);
				}
			}
		});


		bC = new Button(composite,  SWT.PUSH);
		bC.setText("Close");
		GridData bCGd = new GridData();
		bCGd.horizontalAlignment = GridData.FILL;
		bCGd.grabExcessHorizontalSpace = true;
		bC.setLayoutData(bCGd);
		bC.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				if(closePort()){
					bO.setEnabled(true);
					bC.setEnabled(false);
					bK.setEnabled(false);
				}
			}
		});
		bC.setEnabled(false);


		bK = new Button(composite,  SWT.PUSH);
		bK.setText("Configure");
		GridData bKGd = new GridData();
		bKGd.horizontalAlignment = GridData.FILL;
		bKGd.grabExcessHorizontalSpace = true;
		bK.setLayoutData(bKGd);
		bK.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				try{
					serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
				} catch (UnsupportedCommOperationException e) {
					e.printStackTrace();
				}

			}
		});
		bK.setEnabled(false);

		shell.pack();
		shell.open();				
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}


	}

	public static void main(String[] args) {

		Test test = new Test();
		test.createTestShell();
	}
}
